#include "widget.h"
#include "ui_widget.h"
#include <QList>
#include <QMessageBox>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    aboutPage = new AboutPage();
    aboutPage->setDate(__DATE__);

    m_engine = new Engine();
    m_engine->moveToThread(&m_thread);

    connect(&m_thread,&QThread::finished,m_engine,&QObject::deleteLater);
    connect(&m_timer,&QTimer::timeout,this,&Widget::timeout);

    connect(this,&Widget::nextStep,m_engine,&Engine::next);
    connect(this,&Widget::prepare,m_engine,&Engine::prepare);
    connect(this,&Widget::reset,m_engine,&Engine::jumpToStart);

    connect(m_engine,&Engine::prepared,this,&Widget::prepared);
    connect(m_engine,&Engine::finished,this,&Widget::finished);
    connect(m_engine,&Engine::stepFinished,this,&Widget::stepFinished);


    m_thread.start();
    m_data.clear();
    ui->listWidget->addItem("此时的温度场");
    m_cachedRecord.i = 1;
    m_cachedRecord.j = 1;
    m_cachedRecord.step = 1;
    m_cachedRecord.calculated = true;
    m_cachedRecord.type = RECORD_TEMP_AT_TIME;
    m_cachedRecord.data.clear();
}

Widget::~Widget()
{
    delete ui;
    delete aboutPage;
    m_thread.quit();
    m_thread.wait();
}

Parameter* Widget::getParameter(){
    m_parm.init(ui->spin_t0->value(),
                ui->spin_tw->value(),
                ui->spin_a->value(),
                ui->spin_dt->value(),
                ui->spin_l1->value(),
                ui->spin_l2->value(),
                ui->spin_dx->value(),
                ui->spin_dy->value(),
                ui->spin_stop->value());
    return &m_parm;
}

void Widget::lock_input_boxes(bool lock){
    static QList<QWidget*> input_boxes {
        ui->spin_t0,ui->spin_tw,
        ui->spin_a,ui->spin_dt,
        ui->spin_l1,ui->spin_l2,
        ui->spin_dx,ui->spin_dy
    };
    for(auto pWidget:input_boxes){
        pWidget->setEnabled(lock);
    }
}

void Widget::timeout() {
    m_engine->setParameter(*getParameter());
    emit nextStep();
}

void Widget::prepared(bool ok){
    ui->btn_reset->setEnabled(ok);
    ui->btn_start->setEnabled(ok);
}

void Widget::finished(bool ok){
    Q_UNUSED(ok)
    m_timer.stop();
    ui->btn_start->setEnabled(false);
    ui->btn_pause->setEnabled(false);
}

void Widget::stepFinished(bool ok, int curStep, QVector<double> data){

    if (ok){
        ui->progressBar->setMaximum(ui->spin_stop->value());
        ui->progressBar->setValue(curStep);
        m_cachedRecord.calculated = true;
        m_cachedRecord.step = curStep;
        m_cachedRecord.data = data;

        for(auto iter = m_data.begin();iter!=m_data.end();iter++){
            Record &rec = iter.value();
            switch (rec.type) {
            case RECORD_TEMP_AT_TIME:
                if(rec.step == curStep){
                    rec.calculated = true;
                    rec.data = data;
                }
                break;
            case RECORD_TEMP_AT_POINT_AND_TIME:
                if(rec.step == curStep){
                    rec.calculated = true;
                    rec.data.append(data.at(indexOf(rec.i,rec.j,m_parm.xNums)));
                }
                break;
            case RECORD_TEMP_AT_POINT:
                rec.calculated = true;
                rec.data.append(data.at(indexOf(rec.i,rec.j,m_parm.xNums)));
                break;
            }
        }
        auto curItem = ui->listWidget->currentItem();
        QString curText;
        if (curItem != nullptr){
            //艹，在windows上如果没有手动选一个的话这个东西会是一个空指针，会导致程序crash
            //而在linux上就不会有问题，坑死了
            curText = ui->listWidget->currentItem()->text();
        }
        auto type = m_data.value(curText,m_cachedRecord).type;
        if (type == RECORD_TEMP_AT_POINT_AND_TIME){
            ui->widget->setData(m_cachedRecord,m_parm.xNums);
        }else {
            ui->widget->setData(m_data.value(curText,m_cachedRecord),m_parm.xNums);
        }
        ui->widget->setParameter(m_parm,ui->spin_stop->value());


    }else {
        qDebug()<<"计算出错";
    }

}

void Widget::on_btn_prepare_clicked(bool checked)
{
    lock_input_boxes(!checked);
    m_engine->setParameter(*getParameter());
    if (!checked){
        ui->btn_reset->setEnabled(false);
    }
    emit prepare(checked);
}


void Widget::on_btn_start_clicked()
{
    m_timer.start(ui->spin_interval->value());
    ui->btn_pause->setEnabled(true);
    ui->btn_start->setEnabled(false);
}
void Widget::on_btn_pause_clicked()
{
    m_timer.stop();
    ui->btn_start->setEnabled(true);
    ui->btn_pause->setEnabled(false);
}

void Widget::on_btn_reset_clicked()
{
    ui->btn_start->setEnabled(!ui->btn_pause->isEnabled());
    ui->progressBar->setValue(0);
    for(auto iter = m_data.begin();iter!=m_data.end();iter++){
        iter->data.clear();
        iter->calculated = false;
    }
    emit reset();
}



void Widget::on_btn_add_clicked()
{
    Record r;
    QString s;
    r.type = static_cast<RECORD_TYPE>(ui->combo_record_type->currentIndex());
    r.i = ui->spin_i->value();
    r.j = ui->spin_j->value();
    r.step = ui->spin_step->value();
    r.calculated = false;
    switch (r.type) {
        case RECORD_TEMP_AT_TIME:
            s = QString("第%1步时的温度场").arg(r.step);
            break;
        case RECORD_TEMP_AT_POINT:
            s = QString("i=%1,j=%2点的温度变化曲线").arg(r.i).arg(r.j);
            break;
        case RECORD_TEMP_AT_POINT_AND_TIME:
            s = QString("第%1步时i=%2,j=%3点的温度").arg(r.step).arg(r.i).arg(r.j);
            break;
    }
    if (m_data.contains(s)){
        QMessageBox::warning(this,"添加失败","已经添加过了，请勿重复添加相同内容！");
    }else {
        m_data.insert(s,r);
        ui->listWidget->addItem(s);
    }


}


void Widget::on_btn_delete_clicked()
{
    auto index = ui->listWidget->currentRow();
    if (index > 0) {
        auto item = ui->listWidget->takeItem(index);
        auto key = item->data(Qt::DisplayRole).toString();
        m_data.remove(key);
        delete item;
    }
}


void Widget::on_combo_resampling_mode_currentIndexChanged(int index)
{
    ui->widget->setResampleMode(index);
}


void Widget::on_btn_clear_clicked()
{
    if (m_data.size() > 0){
        ui->listWidget->clear();
        ui->listWidget->addItem("此时的温度场");
        m_data.clear();
    }

}

void Widget::on_listWidget_itemClicked(QListWidgetItem *item)
{
    auto currentText = item->text();
    auto record = m_data.value(currentText,m_cachedRecord);
    if (record.calculated){
        if (record.type == RECORD_TEMP_AT_POINT_AND_TIME){
            QMessageBox::information(this,"结果",QString("温度为%1").arg(record.data.at(0)));
        }else{

            ui->widget->setData(record,m_parm.xNums);
            ui->widget->setParameter(m_parm,ui->spin_stop->value());
        }

    }else {
        QMessageBox::information(this,"警告",QString("还没有计算出想要的结果，再耐心等等"));
    }
}

void Widget::on_btn_export_clicked()
{
    ui->widget->exportPlot();
}

void Widget::on_btn_pause_2_clicked()
{
    aboutPage->show();
}
